<!-- 导出数据、模板 -->
<template>
	<!-- #ifdef H5 -->
	<CaButton v-if="Array.isArray(excelData.options)" size="mini" @click="onExcel">
		<div style="display: flex;align-items: center;">
			<IconFont type="xiazai"/>
			{{lang(excelData.title)}}
		</div>
	</CaButton>
	<download-excel v-else :data="excelData.options.data" :fetch="excelData.options.fetch" :fields="excelData.options.fields" :exportFields="excelData.options.exportFields"
		:type="excelData.type" :name="`${excelData.name || 'excelData'}.${excelData.type || 'xls'}`" 
		:header="excelData.options.header" :footer="excelData.options.footer" :worksheet="excelData.options.worksheet" 
		:default-value="excelData.options.defaultValue" :stringifyLongNum="excelData.options.stringifyLongNum" :escapeCsv="excelData.options.escapeCsv"
		:before-generate="beforeGenerate || excelData.beforeGenerate" :before-finish="beforeFinish || excelData.beforeFinish"
	>
	    <slot>
			<CaButton :cancelBubble="false" size="mini">
				<div style="display: flex;align-items: center;">
					<IconFont type="xiazai"/>
					{{lang(excelData.title)}}
				</div>
			</CaButton>
		</slot>
	</download-excel>
	<!-- #endif -->
	<!-- #ifndef H5 -->
	<CaButton size="mini" @click="onExcel">
		<div style="display: flex;align-items: center;">
			<IconFont type="xiazai"/>
			{{lang(excelData.title)}}
		</div>
	</CaButton>
	<!-- #endif -->
</template>

<script>
	
	import base from '@/components/index.vue'
	
	// #ifdef H5
	// https://juejin.cn/post/7103716564985184270
	import XLSX from 'vue-json-excel'
	import xlsx from 'xlsx'
	// #endif
	// #ifndef H5
	import * as XLSX from 'xlsx/dist/xlsx.core.min'
	// #endif
	
	/**
	 * npm install xlsx
	 * npm install vue-json-excel
	 * 241128未测试通过
	 * 
	 * 该组件一般不单独使用，没有做全局处理，最常用的使用途径是core.showModal({excel: {}})
	 */
	
	export default {
		extends: base,
		components: {'download-excel': XLSX || undefined},
		props: {
			// 要生成的数据，如果是多个worksheet，则是数组
			excel: {
				type: [Object, Array],
				required: true,
				default: () => {
					return {
						show: false, // 是否显示
						title: '立即导出', // 导出按钮的名称
						type: 'xls', // 文件类型 xls或者csv。使用xlsx库导出，也支持xlsx
						name: '导出文件', // 导出的文件名称。会自动拼接后缀type
						options: { // 导出表格的配置。可以是数组，数组表示多个表格，每个表格包含以下属性
							// data和fetch不能同时存在
							data: undefined, // Array 需要导出的数据 - 固定数据
							fetch: undefined, // Function 需要导出的数据 - Promise返回数据。data不存在时生效
							fields: undefined, // Object 要导出的JSON对象中的字段，如果没有提供，JSON中的所有属性将被导出
							// exportFields还不知道如何实际使用
							exportFields: undefined, // Object 解决与其他组件的命名冲突问题，用于解决使用变量字段的其他组件（如 vee-validate）的问题。导出字段的工作原来与字段完全相同，
							// header若存在，无法正确识别。如果需要导入的，不建议设置header
							header: '', // String, Array 表格的标题。可以是字符串（一个标题）或字符串数组（多个标题）
							footer: '', // String, Array 表格的页脚。可以是字符串（一个页脚）或字符串数组（多个页脚）
							worksheet: '', // String 工作表选项卡的名称
							// 以下三个如果不存在，默认使用外面的配置
							defaultValue: '-', // 如果某一行没有字段值时候起作用，当行没有字段值时用作回退
							stringifyLongNum: false, // 字符串化长数字和小数（解决数字精度损失的问题），默认值：false
							escapeCsv: true, // 这将转义CSV值，以修复一些excel数字字段的问题。但这会用=" and "包装所有csv数据，以避免你不得不将这个道具设为假。默认值:true
						},
						defaultValue: '-', // 如果某一行没有字段值时候起作用，当行没有字段值时用作回退
						stringifyLongNum: false, // 字符串化长数字和小数（解决数字精度损失的问题），默认值：false
						escapeCsv: true, // 这将转义CSV值，以修复一些excel数字字段的问题。但这会用=" and "包装所有csv数据，以避免你不得不将这个道具设为假。默认值:true
						beforeGenerate: undefined, // Function 在生成/获取数据之前调用方法，例如:显示加载进度
						beforeFinish: undefined, // Function 在下载框弹出之前调用方法的回调，例如:隐藏加载进度
					}
				}
			},
			// 在生成/获取数据之前调用方法，例如:显示加载进度
			beforeGenerate: Function,
			// 在下载框弹出之前调用方法的回调，例如:隐藏加载进度
			beforeFinish: Function,
		},
		watch: {
			excel: {
				handler() {
					this.initial()
				},
				immediate: true
			}
		},
		data() {
			return {
				// 不更改原数值
				excelData: undefined
			}
		},
		methods: {
			// 表格内容初始化
			initial() {
				this.excelData = undefined
				this.excelData = this.core.synctool.copy.all(this.excel)
				const {excelData} = this
				const {options} = excelData
				if (Array.isArray(options)) {
					options.forEach(item => {
						if (item.options) {
							if (item.options.defaultValue === undefined) {
								item.options.defaultValue = excelData.defaultValue
							}
							if (item.options.stringifyLongNum === undefined) {
								if (excelData.stringifyLongNum === undefined) {
									excelData.stringifyLongNum = true
								}
								item.options.stringifyLongNum = excelData.stringifyLongNum
							}
							if (item.options.escapeCsv === undefined) {
								item.options.escapeCsv = excelData.escapeCsv
							}
						}
					})
				} else {
					if (options.defaultValue === undefined) {
						options.defaultValue = excelData.defaultValue
					}
					if (options.stringifyLongNum === undefined) {
						if (excelData.stringifyLongNum === undefined) {
							excelData.stringifyLongNum = true
						}
						options.stringifyLongNum = excelData.stringifyLongNum
					}
					if (options.escapeCsv === undefined) {
						options.escapeCsv = excelData.escapeCsv
					}
				}
			},
			
			// 非H5的导出表格
			onExcel() {
				// #ifdef H5
				// 创建多个 Worksheet 的数据
				const {beforeFinish} = this
				beforeFinish && beforeFinish()
				return this.core.showToast('暂不支持多个工作簿的导出')
				// 以下代码在const ws1 = xlsx.utils.aoa_to_sheet(dataSheet1);时运行不通过
				const dataSheet1 = [
				  ['姓名', '年龄'],
				  ['张三', 25],
				  ['李四', 30]
				];
				
				const dataSheet2 = [
				  ['科目', '成绩'],
				  ['数学', 90],
				  ['英语', 85]
				];
				
				// 创建 Worksheet
				const ws1 = xlsx.utils.aoa_to_sheet(dataSheet1);
				const ws2 = xlsx.utils.aoa_to_sheet(dataSheet2);
				
				// 创建 Workbook 并添加 Worksheet
				const wb = xlsx.utils.book_new();
				xlsx.utils.book_append_sheet(wb, ws1, 'Sheet1');
				xlsx.utils.book_append_sheet(wb, ws2, 'Sheet2');
				
				// 生成 Excel 文件
				const wbout = xlsx.write(wb, { bookType: 'xlsx', type: 'binary' });
				
				// 将二进制数据转换为 Blob 对象
				function s2ab(s) {
				  const buf = new ArrayBuffer(s.length);
				  const view = new Uint8Array(buf);
				  for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xFF;
				  return buf;
				}
				
				const blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' });
				
				// 创建下载链接并触发下载
				const url = URL.createObjectURL(blob);
				const a = document.createElement('a');
				a.href = url;
				a.download = 'multi_sheet_excel.xlsx';
				a.click();
				URL.revokeObjectURL(url);
				
				// #endif
				// #ifndef H5
				this.core.file.excelData.write(this.excelData)
				// #endif
			}
		}
	}
</script>

<style>
</style>